home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / fsstat / RCS / fsstats.awk,v < prev    next >
Encoding:
Text File  |  1988-12-06  |  17.3 KB  |  581 lines

  1. head     1.1;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @@;
  7.  
  8.  
  9. 1.1
  10. date     88.12.06.09.51.47;  author douglis;  state Exp;
  11. branches ;
  12. next     ;
  13.  
  14.  
  15. desc
  16. @awk script to combine output and write out summary information for deletion
  17. >> histograms and i/o rates.
  18. @
  19.  
  20.  
  21.  
  22. 1.1
  23. log
  24. @Initial revision
  25. @
  26. text
  27. @# This file combines the output from one or more invocations of fsstat
  28. # and writes the relevant data to standard out.  So far, the only data
  29. # combined are the counts of cache & disk I/O by file type, and the
  30. # deletion counts by file type.  To be added: overall I/O, and
  31. # histogram information (deletion distribution function).
  32.  
  33. # Note: some of the counts tend to overflow awk's ideas of integers.
  34. # Since awk keeps numbers internally as floating-point, we can print
  35. # them as such, but then the accuracy diminishes somewhat.  However,
  36. # the margin of error should be small.
  37.  
  38. # Initialization.  Define a few constants.  Arrays could be
  39. # initialized to 0, but awk does that for us automatically.  In some
  40. # places it would be nicer to use string subscripts, but awk used to die
  41. # with a Mem_Alloc error when I tried.  In addition, by using integers,
  42. # we can use for statements to iterate through them.
  43.  
  44. BEGIN { TEMP = 0; SWAP = 1; OBJ = 2; BINARY = 3; OTHER = 4; TOTAL = 5; 
  45.     WT_TOTAL = 1; WT_DATA = 2; WT_INDEX = 3; WT_DESC = 4; WT_DIR = 5; 
  46.     WT_VM = 6;
  47.         strings[TEMP] = "temp"; strings[SWAP] = "swap"; strings[OBJ] = "obj";
  48.     strings[BINARY] = "bin"
  49.         strings[OTHER] = "other"; state = 0; maxRow = -1; row = -1;
  50.         lastHost = ""; longestUptime = 0;
  51.     numHosts = 0; numFiles = 0;
  52. }
  53.  
  54. # The general methodology for determining what data we're looking at
  55. # is to look for a well-known string and set a state variable.
  56. # Since the inputs are effectively concatenated, each time we hit the
  57. # first line of an fsstat output, we reset the state to 0 and
  58. # initialize the "row" variable.  The states are as follows:
  59. #    state        meaning
  60. #    0        waiting to get to the interesting statistics
  61. #    1        gathering file type I/O statistics
  62. #    2        gathering overall deletion statistics
  63. #    3        gathering deletion histogram statistics
  64.  
  65. /^Fs Stats:/{state = 0; if (row > maxRow) maxRow = row; row = -1; numFiles++}
  66.  
  67. # Parse the uptime information, in the form:
  68. #        mint.Berkeley.EDU*   up   1+08:35   ...
  69. /^ +[a-z]*\.Berkeley\.EDU[ \*] *(up|down)/ {
  70.     n = split($1, spl, "*")
  71.     thisHost = spl[1]
  72.     if (thisHost != lastHost) {
  73.     lastHost = thisHost
  74.         numHosts ++
  75.     }
  76.     thisUp = $3
  77.     n = split(thisUp, spl, "+")
  78.     if (n == 1) {
  79.     days = 0
  80.     } else {
  81.     days = spl[1]
  82.     thisUp = spl[2]
  83.     }
  84.     n = split(thisUp, spl, ":")
  85.     if (n == 1) {
  86.         hours = 0
  87.     minutes = thisUp
  88.     } else {
  89.     hours = spl[1]
  90.     minutes = spl[2]
  91.     }
  92.     upTime = ((24 * days) + hours) * 60 + minutes
  93.     if (upTime > longestUptime) {
  94.         longestUptime = upTime
  95.     }
  96.     totalUptime += upTime
  97. #    print "days = " days " hours = " hours " minutes = " minutes " total = " totalUptime " upTime = " upTime
  98. }
  99.  
  100.  
  101. /^ READ *[0-9]/ {
  102.     blocksRead += $2; dirtyHits += $4; cleanHits += $6
  103. }
  104.  
  105. /^ WRITE *[0-9]/ {
  106.     blocksWritten += $2
  107. }
  108.  
  109. /^ WRITETHRU [0-9]/ {
  110.     writeThrus[WT_TOTAL] += $2
  111.     writeThrus[WT_DATA] += $4
  112.     writeThrus[WT_INDEX] += $7
  113.     writeThrus[WT_DESC] += $10
  114.     writeThrus[WT_DIR] += $13
  115.     writeThrus[WT_VM] += $16
  116. }
  117.  
  118. /^ Read/ {
  119.     cacheReads[TOTAL] += $2
  120.     remoteReads += $3
  121.     diskReads[TOTAL] += $5
  122.     rawReads += $7
  123. }
  124.  
  125. /^ Write/ {
  126.     cacheWrites[TOTAL] += $2
  127.     remoteWrites += $3
  128.     diskWrites[TOTAL] += $5
  129.     rawWrites += $7
  130. }
  131.  
  132. # The count of calls has the following format (e.g.):
  133. # "Count of calls: open(R) N   (W) N   (R/W) N   set attributes 12"
  134. /^Count of calls:/ {
  135.     callCounts[0] += $5; callCounts[1] += $7;
  136.     callCounts[2] += $9; callCounts[3] += $12
  137. }
  138.  
  139. /^File type.*Cache/ { state = 1}
  140. /^File type.*Deleted/ {state = 2}
  141. /^Deletion histogram/ {state = 3}
  142.  
  143. # Each of the data lines that we care about is preceded by one of the
  144. # type strings.  (Unfortunately, I don't think we can make that a
  145. # variable unless we make this script go through cpp or something.)
  146. # Given a particular string, check the state and add to the
  147. # appropriate field.  The I/O and overall deletion counts are just
  148. # regular arrays.  The histogram is kept in separate arrays for each
  149. # file type, indexed by row number (corresponding to time bucket).
  150. # Awk doesn't allow 2-dimensional arrays. 
  151.  
  152. /^ *temp/ {
  153.     if (state == 0) {
  154.         print("Error");
  155.     } else if (state == 1) {
  156.         cacheReads[TEMP] += $2
  157.         cacheWrites[TEMP] += $4
  158.         diskReads[TEMP] += $6
  159.         diskWrites[TEMP] += $8
  160.     } else if (state == 2) {
  161.         deletions[TEMP] += $2
  162.     } else {
  163.         row++
  164.         tempDels[row] += $NF
  165.     }
  166. }
  167. /^ *swap/ {
  168.     if (state == 0) {
  169.         print("Error");
  170.     } else if (state == 1) {
  171.         cacheReads[SWAP] += $2
  172.         cacheWrites[SWAP] += $4
  173.         diskReads[SWAP] += $6
  174.         diskWrites[SWAP] += $8
  175.     } else if (state == 2) {
  176.         deletions[SWAP] += $2
  177.     } else {
  178.         swapDels[row] += $NF
  179.     }
  180. }
  181.  
  182. /^ *obj/ {
  183.     if (state == 0) {
  184.         print("Error");
  185.     } else if (state == 1) {
  186.         cacheReads[OBJ] += $2
  187.         cacheWrites[OBJ] += $4
  188.         diskReads[OBJ] += $6
  189.         diskWrites[OBJ] += $8
  190.     } else if (state == 2) {
  191.         deletions[OBJ] += $2
  192.     } else {
  193.         objDels[row] += $NF
  194.     }
  195. }
  196. /^ *bin/ {
  197.     if (state == 0) {
  198.         print("Error");
  199.     } else if (state == 1) {
  200.         cacheReads[BINARY] += $2
  201.         cacheWrites[BINARY] += $4
  202.         diskReads[BINARY] += $6
  203.         diskWrites[BINARY] += $8
  204.     } else if (state == 2) {
  205.         deletions[BINARY] += $2
  206.     } else {
  207.         binDels[row] += $NF
  208.     }
  209. }
  210. /^ *other/ {
  211.     if (state == 0) {
  212.         print("Error");
  213.     } else if (state == 1) {
  214.         cacheReads[OTHER] += $2
  215.         cacheWrites[OTHER] += $4
  216.         diskReads[OTHER] += $6
  217.         diskWrites[OTHER] += $8
  218.     } else if (state == 2) {
  219.         deletions[OTHER] += $2
  220.     } else {
  221.         otherDels[row] += $NF
  222.         totalDels[row] += tempDels[row] + swapDels[row] + \
  223.         objDels[row] + binDels[row] + otherDels[row]
  224.     }
  225. }
  226. /^Total/ {
  227.     if (state == 2) {
  228.         deletions[TOTAL] += $2
  229.     }
  230. }
  231.  
  232. # Processing done after all counts have been finished.  First,
  233. # catch the last value of row before exiting.  Output total uptime.
  234. # Calculate the total number of I/O's and come up with the ratios.
  235. END {
  236.     if (row > maxRow) maxRow = row
  237.  
  238.     days = totalUptime / (24 * 60)
  239.     minutes = totalUptime % (24 * 60)
  240.     hours = minutes / 60
  241.     minutes = minutes % 60
  242. #    print "days = " days " hours = " hours " minutes = " minutes " total = " totaUptime " upTime = " upTime
  243. #    printf ("%d %d %d\n", days, hours, minutes)
  244.     if (days >= 1) {
  245.         dayString = sprintf("%d+", days)
  246.     } else {
  247.         dayString = ""
  248.     }
  249.     if (minutes < 10) {
  250.     minutesString = sprintf("0%d", minutes)
  251.     } else {
  252.         minutesString = minutes
  253.     }
  254.     printf("Total combined uptime for %d host(s) over %d files:  %s%d:%s\n", \
  255.        numHosts, numFiles, dayString, hours, minutesString)
  256.  
  257.     days = longestUptime / (24 * 60)
  258.     minutes = longestUptime % (24 * 60)
  259.     hours = minutes / 60
  260.     minutes = minutes % 60
  261.     if (days >= 1) {
  262.         dayString = sprintf("%d+", days)
  263.     } else {
  264.         dayString = ""
  265.     }
  266.     if (minutes < 10) {
  267.     minutesString = sprintf("0%d", minutes)
  268.     } else {
  269.         minutesString = minutes
  270.     }
  271.     printf("Longest single uptime:  %s%d:%s\n", dayString, hours, minutesString)
  272.  
  273. # Output the interesting cumulative statistics.  First, the block cache info.
  274.  
  275.     print "Block Cache Statistics (in blocks):"
  276.     printf(" READ    %10.0f   dr_hits %10.0f   cl_hits  %10.0f   hit ratio %3d\n", \
  277.          blocksRead, dirtyHits, cleanHits, \
  278.          100 * (dirtyHits + cleanHits) / blocksRead)
  279.     if (blocksWritten > 0) {
  280.          ratio = writeThrus[WT_TOTAL] / blocksWritten * 100
  281.     } else {
  282.          ratio = 0
  283.     }
  284.     printf(" WRITE   %10.0f   writethrus %10.0f                       tfc ratio %3d\n", \
  285.             blocksWritten, writeThrus[WT_TOTAL], ratio)
  286.  
  287.     print "\nByte transfers:\n"
  288.     print "Bytes:          cache          remote               disk           raw disk"
  289.  
  290.     cacheBytes = cacheReads[TOTAL];
  291.     ratio = remoteReads / cacheBytes * 100.;
  292.     printf(" Read   %13.0f   %13.0f %3d%%", cacheBytes, remoteReads, ratio)
  293.  
  294.     thruBytes = diskReads[TOTAL];
  295.     ratio = thruBytes / cacheBytes * 100.;
  296.     printf(" %13.0f %3d%%", thruBytes, ratio);
  297.  
  298.     ratio = rawReads / cacheBytes * 100.;
  299.     printf(" %13.0f %3d%%\n", rawReads, ratio);
  300.     cacheBytes = cacheWrites[TOTAL];
  301.     ratio = remoteWrites / cacheBytes * 100.;
  302.     printf(" Write  %13.0f   %13.0f %3d%%", cacheBytes, remoteWrites, ratio)
  303.  
  304.     thruBytes = diskWrites[TOTAL];
  305.     ratio = thruBytes / cacheBytes * 100.;
  306.     printf(" %13.0f %3d%%", thruBytes, ratio);
  307.  
  308.     ratio = rawWrites / cacheBytes * 100.;
  309.     printf(" %13.0f %3d%%\n", rawWrites, ratio);
  310.  
  311.     print "\nread/write ratios:"
  312.     if (cacheWrites[TOTAL] > 0) {
  313.     allCacheRatio = cacheReads[TOTAL] / cacheWrites[TOTAL];
  314.     } else {
  315.     allCacheRatio = 0
  316.     }
  317.     if (diskWrites[TOTAL] > 0) {
  318.     allDiskRatio = diskReads[TOTAL] / diskWrites[TOTAL];
  319.     } else {
  320.     allDiskRatio = 0
  321.     }
  322.     if (rawWrites > 0) {
  323.     rawRatio = rawReads / rawWrites;
  324.     } else {
  325.     rawRatio = 0
  326.     }
  327.     if (rawWrites + diskWrites[TOTAL] > 0) {
  328.     combRatio = (rawReads + diskReads[TOTAL]) / \
  329.             (rawWrites + diskWrites[TOTAL]);
  330.     } else {
  331.     combRatio = 0
  332.     }
  333.     printf ("Cache: %5.2f\tDisk: %5.2f\tRaw disk: %5.2f\t  All disk: %5.2f\n\n", \
  334.         allCacheRatio, allDiskRatio, rawRatio, combRatio)
  335.  
  336. #
  337. # Call counts
  338.     print "Count of calls:"
  339.     printf("\topen for reading: %15d\n", callCounts[0]);
  340.     printf("\t  \"      writing: %15d\n", callCounts[1]);
  341.     printf("\t  \"   read/write: %15d\n", callCounts[2]);
  342.     printf("\t  set attributes: %15d\n", callCounts[3]);
  343.     print ""
  344.  
  345. #
  346. # Per-type file I/O
  347. #
  348.  
  349. # Recalculate totals to make sure the percentages add up correctly.
  350.  
  351.     cacheReads[TOTAL] = cacheReads[TEMP] + cacheReads[SWAP] + \
  352.         cacheReads[OBJ] + cacheReads[BINARY] + cacheReads[OTHER]
  353.     cacheWrites[TOTAL] = cacheWrites[TEMP] + cacheWrites[SWAP] + \
  354.         cacheWrites[OBJ] + cacheWrites[BINARY] + cacheWrites[OTHER]
  355.     diskReads[TOTAL] = diskReads[TEMP] + diskReads[SWAP] + \
  356.         diskReads[OBJ] + diskReads[BINARY] + diskReads[OTHER]
  357.     diskWrites[TOTAL] = diskWrites[TEMP] + diskWrites[SWAP] + \
  358.         diskWrites[OBJ] + diskWrites[BINARY] + diskWrites[OTHER]
  359.  
  360.     if (cacheReads[TOTAL] > 0) {
  361.     cacheReadRatio[TEMP] = cacheReads[TEMP] / cacheReads[TOTAL]
  362.     cacheReadRatio[SWAP] = cacheReads[SWAP] / cacheReads[TOTAL]
  363.     cacheReadRatio[OBJ] = cacheReads[OBJ] / cacheReads[TOTAL]
  364.     cacheReadRatio[BINARY] = cacheReads[BINARY] / cacheReads[TOTAL]
  365.     cacheReadRatio[OTHER] = cacheReads[OTHER] / cacheReads[TOTAL]
  366.      } else {
  367.     cacheReadRatio[TEMP] = 0
  368.     cacheReadRatio[SWAP] = 0
  369.     cacheReadRatio[OBJ] = 0
  370.     cacheReadRatio[BINARY] = 0
  371.     cacheReadRatio[OTHER] = 0
  372.     }
  373.     if (cacheWrites[TOTAL] > 0) {
  374.     cacheWriteRatio[TEMP] = cacheWrites[TEMP] / cacheWrites[TOTAL]
  375.     cacheWriteRatio[SWAP] = cacheWrites[SWAP] / cacheWrites[TOTAL]
  376.     cacheWriteRatio[OBJ] = cacheWrites[OBJ] / cacheWrites[TOTAL]
  377.     cacheWriteRatio[BINARY] = cacheWrites[BINARY] / cacheWrites[TOTAL]
  378.     cacheWriteRatio[OTHER] = cacheWrites[OTHER] / cacheWrites[TOTAL]
  379.      } else {
  380.     cacheWriteRatio[TEMP] = 0
  381.     cacheWriteRatio[SWAP] = 0
  382.     cacheWriteRatio[OBJ] = 0
  383.     cacheWriteRatio[BINARY] = 0
  384.     cacheWriteRatio[OTHER] = 0
  385.     }
  386.     if (diskReads[TOTAL] > 0) {
  387.     diskReadRatio[TEMP] = diskReads[TEMP] / diskReads[TOTAL]
  388.     diskReadRatio[SWAP] = diskReads[SWAP] / diskReads[TOTAL]
  389.     diskReadRatio[OBJ] = diskReads[OBJ] / diskReads[TOTAL]
  390.     diskReadRatio[BINARY] = diskReads[BINARY] / diskReads[TOTAL]
  391.     diskReadRatio[OTHER] = diskReads[OTHER] / diskReads[TOTAL]
  392.      } else {
  393.     diskReadRatio[TEMP] = 0
  394.     diskReadRatio[SWAP] = 0
  395.     diskReadRatio[OBJ] = 0
  396.     diskReadRatio[BINARY] = 0
  397.     diskReadRatio[OTHER] = 0
  398.     }
  399.     if (diskWrites[TOTAL] > 0) {
  400.     diskWriteRatio[TEMP] = diskWrites[TEMP] / diskWrites[TOTAL]
  401.     diskWriteRatio[SWAP] = diskWrites[SWAP] / diskWrites[TOTAL]
  402.     diskWriteRatio[OBJ] = diskWrites[OBJ] / diskWrites[TOTAL]
  403.     diskWriteRatio[BINARY] = diskWrites[BINARY] / diskWrites[TOTAL]
  404.     diskWriteRatio[OTHER] = diskWrites[OTHER] / diskWrites[TOTAL]
  405.      } else {
  406.     diskWriteRatio[TEMP] = 0
  407.     diskWriteRatio[SWAP] = 0
  408.     diskWriteRatio[OBJ] = 0
  409.     diskWriteRatio[BINARY] = 0
  410.     diskWriteRatio[OTHER] = 0
  411.     }
  412.  
  413.     print "Per-type file I/O, in bytes:"
  414.     print "\nFile type    Cache(R)          Cache(W)           Disk(R)           Disk(W)"
  415.    
  416.     for (i = TEMP; i < TOTAL; i++) {
  417.         printf("%-5s ", strings[i]);
  418.         printf(" %12.0f %3d%%", cacheReads[i], cacheReadRatio[i] * 100  + .5)
  419.         printf(" %12.0f %3d%%", cacheWrites[i], cacheWriteRatio[i] * 100  + .5)
  420.         printf(" %12.0f %3d%%", diskReads[i], diskReadRatio[i] * 100  + .5)
  421.         printf(" %12.0f %3d%%\n", diskWrites[i], diskWriteRatio[i] * 100  + .5)
  422.     }
  423.  
  424. # Output the total per-type deletion counts and the R/W ratios
  425.     if (deletions[TOTAL] > 0) {
  426.         hdr = "        Bytes Deleted"
  427.         tail = sprintf(" %15.0f 100%%", deletions[TOTAL]);
  428.     } else {
  429.         hdr = ""; tail = ""
  430.     }
  431.     printf("\nFile type   Cache R/W    Disk R/W    Read Hits   Write Tfc%s", hdr);
  432.     for (i = 0; i < TOTAL; i++) {
  433.     if (cacheWrites[i] > 0) {
  434.         cacheRatio = cacheReads[i] / cacheWrites[i];
  435.         trafficRatio = diskWrites[i] / cacheWrites[i];
  436.     } else {
  437.         cacheRatio = 0
  438.         trafficRatio = 0
  439.     }
  440.     if (cacheReads[i] > 0) {
  441.         readHitRatio = 1 - diskReads[i] / cacheReads[i];
  442.     } else {
  443.         readHitRatio = 0
  444.     }
  445.     if (diskWrites[i] > 0) {
  446.         diskRatio = diskReads[i] / diskWrites[i];
  447.     } else {
  448.         diskRatio = 0
  449.     }
  450.         if (deletions[TOTAL] > 0) {
  451.         delStr = sprintf(" %15.0f %3d%%", deletions [i], \
  452.             deletions [i] / deletions[TOTAL] * 100 + 0.5)
  453.     } else {
  454.         delStr = ""
  455.     }
  456.     printf("\n%-5s          %6.2f      %6.2f       %6.2f      %6.2f%s", \
  457.            strings[i], cacheRatio, diskRatio, readHitRatio, \
  458.            trafficRatio, delStr);
  459.     }
  460.     if (cacheReads[TOTAL] > 0) {
  461.     readHitRatio = 1 - diskReads[TOTAL] / cacheReads[TOTAL];
  462.     } else {
  463.     readHitRatio = 0
  464.     }
  465.     if (cacheWrites[TOTAL] > 0) {
  466.     trafficRatio = diskWrites[TOTAL] / cacheWrites[TOTAL];
  467.     } else {
  468.     trafficRatio = 0
  469.     }
  470.     printf("\nTotal          %6.2f      %6.2f       %6.2f      %6.2f%s\n", \
  471.         allCacheRatio, allDiskRatio, readHitRatio, trafficRatio, tail);
  472.     if (totalDels[maxRow] > 0) {
  473.         timeStrings[0] = "1 sec "
  474.         timeStrings[1] = "2 secs"
  475.     timeStrings[2] = "3 secs"
  476.     timeStrings[3] = "4 secs"
  477.     timeStrings[4] = "5 secs"
  478.     timeStrings[5] = "6 secs"
  479.     timeStrings[6] = "7 secs"
  480.     timeStrings[7] = "8 secs"
  481.     timeStrings[8] = "9 secs"
  482.     timeStrings[9] = "10 secs"
  483.     timeStrings[10] = "20 secs"
  484.     timeStrings[11] = "30 secs"
  485.     timeStrings[12] = "40 secs"
  486.     timeStrings[13] = "50 secs"
  487.     timeStrings[14] = "1 min "
  488.     timeStrings[15] = "2 mins"
  489.     timeStrings[16] = "3 mins"
  490.     timeStrings[17] = "4 mins"
  491.     timeStrings[18] = "5 mins"
  492.     timeStrings[19] = "6 mins"
  493.     timeStrings[20] = "7 mins"
  494.     timeStrings[21] = "8 mins"
  495.     timeStrings[22] = "9 mins"
  496.     timeStrings[23] = "10 mins"
  497.     timeStrings[24] = "20 mins"
  498.     timeStrings[25] = "30 mins"
  499.     timeStrings[26] = "40 mins"
  500.     timeStrings[27] = "50 mins"
  501.     timeStrings[28] = "1 hr "
  502.     timeStrings[29] = "2 hrs"
  503.     timeStrings[30] = "3 hrs"
  504.     timeStrings[31] = "4 hrs"
  505.     timeStrings[32] = "5 hrs"
  506.     timeStrings[33] = "6 hrs"
  507.     timeStrings[34] = "7 hrs"
  508.     timeStrings[35] = "8 hrs"
  509.     timeStrings[36] = "9 hrs"
  510.     timeStrings[37] = "10 hrs"
  511.     timeStrings[38] = "15 hrs"
  512.     timeStrings[39] = "20 hrs"
  513.     timeStrings[40] = "1 day "
  514.     timeStrings[41] = "2 days"
  515.     timeStrings[42] = "3 days"
  516.     timeStrings[43] = "4 days"
  517.     timeStrings[44] = "5 days"
  518.     timeStrings[45] = "6 days"
  519.     timeStrings[46] = "7 days"
  520.     timeStrings[47] = "8 days"
  521.     timeStrings[48] = "9 days"
  522.     timeStrings[49] = "10 days"
  523.     timeStrings[50] = "20 days"
  524.     timeStrings[51] = "30 days"
  525.     timeStrings[52] = "40 days"
  526.     timeStrings[53] = "50 days"
  527.     timeStrings[54] = "60 days"
  528.     timeStrings[55] = "90 days"
  529.     timeStrings[56] = "120 days"
  530.     timeStrings[57] = "180 days"
  531.     timeStrings[58] = "240 days"
  532.     timeStrings[59] = "300 days"
  533.     timeStrings[60] = "360 days"
  534.     timeStrings[61] = ">360 days"
  535.         numTimesToPrint = maxRow
  536.  
  537.     printf(" \nPercentiles for bytes deleted, by type.  Total is in 1K blocks:\n\n");
  538.     printf("      Time   %6s %6s %6s %6s %6s   Cumulative         Cum. Total\n", \
  539.              strings[0],  strings[1], strings[2], strings[3], strings[4])
  540.     for (row = 0; row <= maxRow; row++) {
  541.         printf("%10s    ", timeStrings[row]);
  542.             if (tempDels[maxRow] > 0) {
  543.              ratio = tempDels[row] / tempDels[maxRow];
  544.         } else {
  545.              ratio = 0;
  546.         }
  547.         printf("%5.0f  ", ratio * 100);
  548.             if (swapDels[maxRow] > 0) {
  549.              ratio = swapDels[row] / swapDels[maxRow];
  550.         } else {
  551.              ratio = 0;
  552.         }
  553.         printf("%5.0f  ", ratio * 100);
  554.             if (objDels[maxRow] > 0) {
  555.              ratio = objDels[row] / objDels[maxRow];
  556.         } else {
  557.              ratio = 0;
  558.         }
  559.         printf("%5.0f  ", ratio * 100);
  560.             if (binDels[maxRow] > 0) {
  561.              ratio = binDels[row] / binDels[maxRow];
  562.         } else {
  563.              ratio = 0;
  564.         }
  565.         printf("%5.0f  ", ratio * 100);
  566.             if (otherDels[maxRow] > 0) {
  567.              ratio = otherDels[row] / otherDels[maxRow];
  568.         } else {
  569.              ratio = 0;
  570.         }
  571.         printf("%5.0f  ", ratio * 100);
  572.         printf("      %5.0f    %15.0f\n", \
  573.                  totalDels[row] / totalDels[maxRow] * 100, totalDels[row]);
  574.  
  575.     }
  576.     }
  577.     print ""
  578. }
  579. @
  580.